package com.softwareconstruction.management;

import com.softwareconstruction.paper.Paper;
import com.softwareconstruction.paper.PaperType;
import com.softwareconstruction.selection.PaperSelection;
import com.softwareconstruction.strategy.PaperSelectionStrategy;
import com.softwareconstruction.strategy.RandomSelectionStrategy;
import com.softwareconstruction.student.Student;

import java.util.*;

/**
 * 论文清单管理类，使用策略模式实现不同的选择算法
 */
public class PaperList {
    private String teacher;
    private List<Paper> papers;
    private PaperSelection selections;
    private PaperSelectionStrategy strategy = new RandomSelectionStrategy(); // 默认策略

    public PaperList(String teacher, List<Paper> papers) {
        this.teacher = teacher;
        this.papers = papers;
        this.selections = new PaperSelection();
    }

    public void setSelectionStrategy(PaperSelectionStrategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 根据学生偏好随机选择论文
     * @param student 学生对象
     * @return 选择的论文列表
     * @throws NoEnoughPapersException 如果可选论文数量不足
     */
    public List<Paper> selectPaperByRandom(Student student) throws NoEnoughPapersException {
        List<Paper> availablePapers = getUnselectedPapersByType(student.getPreferredPaperType());
        if (availablePapers.size() < student.getPreferredQuantity()) {
            throw new NoEnoughPapersException("学生 " + student.getName() + " 希望选论文 " +
                    student.getPreferredQuantity() + " 篇，但目前只有 " + availablePapers.size() + " 篇可选");
        }

        List<Paper> selectedPapers = strategy.selectPapers(availablePapers, student.getPreferredQuantity());
        for (Paper paper : selectedPapers) {
            selections.addSelection(student, paper);
        }
        return selectedPapers;
    }

    public PaperSelection getSelectionResult() {
        return selections;
    }

    private List<Paper> getUnselectedPapersByType(PaperType type) {
        List<Paper> results = new ArrayList<>();
        for (Paper paper : papers) {
            if (!selections.isSelected(paper)) {
                if (type == PaperType.Any ||
                        (type == PaperType.Thesis && paper instanceof Thesis) ||
                        (type == PaperType.ConferencePaper && paper instanceof ConferencePaper) ||
                        (type == PaperType.JournalPaper && paper instanceof JournalPaper)) {
                    results.add(paper);
                }
            }
        }
        return results;
    }
}